package com.wlf.server.common.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.wlf.server.common.em.Const;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wlf.server.common.entity.SysSerial;
import com.wlf.server.common.mapper.SysSerialMapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 自定义序列用来代替自增数据库主键，
 * 有些时候我们需要一些每天重置的流水号来统计一些数据，
 * 比如订单流水号，这时候我们需要一个自增的流水，而且每天都会从零开始，
 * 这个就是为了实现这种需求。
 * 这目前流水号有四周重置形式，
 * 按天重置，按月重置，按年重置，和不重置。
 * 长度的话，自己根据实际业务情况来设置即可
 */
@Service
public class SysSerialService extends ServiceImpl<SysSerialMapper, SysSerial> {

    /**
     * 获取序列
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public String getSerial(Const.SerialType type){
        SysSerial serial = this.getById(type.name());
        if (serial == null){ // 不存在序列的情况
            SysSerial saveTemp = new SysSerial();
            saveTemp.setSerialType(type.name());
            saveTemp.setSerialNo(1);
            saveTemp.setGenerateDate(DateUtil.date().toString(type.getType().getFormat()));
            this.save(saveTemp);
            return StrUtil.padPre(String.valueOf(saveTemp.getSerialNo()),type.getLength(),"0");
        } else {
            switch (type.getType()) {
                case DAY, MONTH, YEAR -> {
                    String formatDate = DateUtil.date().toString(type.getType().getFormat());
                    SysSerial saveTemp = new SysSerial();
                    saveTemp.setSerialType(type.name());
                    if (formatDate.equals(serial.getGenerateDate())) {
                        saveTemp.setSerialNo(serial.getSerialNo() + 1);
                        this.updateById(saveTemp);
                    } else {
                        saveTemp.setGenerateDate(DateUtil.date().toString(type.getType().getFormat()));
                        saveTemp.setSerialNo(1);
                        this.save(saveTemp);
                    }
                    return StrUtil.padPre(String.valueOf(saveTemp.getSerialNo()), type.getLength(), "0");
                }
                case NONE -> {
                    SysSerial updateTemp = new SysSerial();
                    updateTemp.setSerialType(serial.getSerialType());
                    updateTemp.setSerialNo(serial.getSerialNo() + 1);
                    this.updateById(updateTemp);
                    return StrUtil.padPre(String.valueOf(updateTemp.getSerialNo()), type.getLength(), "0");
                }
            }
        }
        return "";
    }
}
